#include "cEventList.hh"
#include <sstream>
#include <string.h>
#include <math.h>
#include "TH1F.h"
#include "TH2F.h"
#include <iomanip>
#include <algorithm>
#include "stdint.h"
#include <set>
#include "TCanvas.h"

using namespace std;

cEventList::cEventList() {

}
cEventList::cEventList(int id) {
	stringstream ss;
	ss << "detector_" << id;
	strcpy(name, ss.str().c_str());
	markedPileUp = 0;
	markedDeadTime = 0;
	realTime = 0;
	//data.resize(data.max_size()/2);
	data.reserve(50000000);
	eventsStored = 1000;
}

cEventList::cEventList(char name2[256]) {
	markedPileUp = 0;
	markedDeadTime = 0;
	realTime = 0;
	strcpy(name, name2);
	//data.resize(data.max_size()/2);
	data.reserve(50000000);
	eventsStored = 1000;
}

//int cEventList::ReadFromDir(char dirname[256]){
//
//		int fileOk;
//		fileOk=1;
//
//		int i;
//		i=0;
//
//		while(fileOk){
//			stringstream ss;
//			//ss<<dirname<<"/Card0230_"<<setfill('0')<<setw(4)<<i+1<<"_events.txt";
//			ss<<dirname<<"/Card1401_"<<setfill('0')<<setw(4)<<i+1<<".evt";
//						cout<<"reading "<<ss.str().c_str()<<endl;
//			fileOk=ReadFileBin(&ss);
//			if(fileOk) cout<<"		file read succesfully; total no of events:"<<size()<<endl;
//			cout<<"                                       last timestamp in file "<<cCaenEvent::lastTimestamp<<" (sec)  corrected:"<<cCaenEvent::lastTimestamp+cCaenEvent::correctionTime<<"(sec)"<<endl;
//
//			i++;
//			//DoOtherMath();
//			//this->Print();
//		};
//
//
//		DoOtherMath();
//
//		return 1;
//}

/*int cEventList::ReadFromDir(char dirname[256],int detId){

 int fileOk;
 fileOk=1;

 int i;
 i=0;

 while(fileOk){
 stringstream ss;
 //ss<<dirname<<"/Card0230_"<<setfill('0')<<setw(4)<<i+1<<"_events.txt";
 ss<<dirname<<"/Card1401_"<<setfill('0')<<setw(4)<<i+1<<".evt";
 cout<<"reading "<<ss.str().c_str()<<endl;
 fileOk=ReadFileBin(&ss,detId);
 if(fileOk) cout<<"		file read succesfully; total no of events:"<<size()<<endl;
 cout<<"                                       last timestamp in file "<<cCaenEvent::lastTimestamp<<" (sec)  corrected:"<<cCaenEvent::lastTimestamp+cCaenEvent::correctionTime<<"(sec)"<<endl;

 i++;
 //DoOtherMath();
 //this->Print();
 };


 DoOtherMath();

 return 1;
 }*/
//int cEventList::ReadFromDir(char dirname[256], int detId, int cardNo) {
//
//	int fileOk;
//	fileOk = 1;
//
//	int i;
//	i = 0;
//
//	while (fileOk) {
//		stringstream ss;
//		//ss<<dirname<<"/Card0230_"<<setfill('0')<<setw(4)<<i+1<<"_events.txt";
//		ss << dirname << "/Card" << cardNo << "_" << setfill('0') << setw(4)
//				<< i + 1 << ".evt";
//		cout << "reading " << ss.str().c_str() << endl;
//		fileOk = ReadFileBin(&ss, detId);
//		if (fileOk)
//			cout << "		file read succesfully; total no of events:" << size()
//					<< endl;
//		cout << "                                       last timestamp in file "
//				<< cCaenEvent::lastTimestamp << " (sec)  corrected:"
//				<< cCaenEvent::lastTimestamp + cCaenEvent::correctionTime
//				<< "(sec)" << endl;
//
//		i++;
//		//DoOtherMath();
//		//this->Print();
//	};
//
//	//DoOtherMath();
//
//	return 1;
//}
int cEventList::ReadFromDir(char dirname[256], int cardNo, int fileNo) {

	int fileOk;
	fileOk = 1;

	int i;
	i = 0;

	//while (fileOk) {
	stringstream ss;
	//ss<<dirname<<"/Card0230_"<<setfill('0')<<setw(4)<<i+1<<"_events.txt";
	ss << dirname << "/Card" << cardNo << "_" << setfill('0') << setw(4)
			<< fileNo << ".evt";
	cout << "reading " << ss.str().c_str() << endl;
	fileOk = ReadFileBin(&ss);
	if (fileOk) {
		cout << "		file read successfully; total no of events:" << size()
				<< endl;
		cout << "                                       last timestamp in file "
				<< cCaenEvent::lastTimestamp << " (sec)  corrected:"
				<< cCaenEvent::lastTimestamp + cCaenEvent::correctionTime
				<< "(sec)" << endl;
	} else
		fileNo = -10;

	return fileNo + 1;
}

int cEventList::ReadFromDir(char dirname[256], int cardNo) {

	int fileOk;
	fileOk = 1;

	int i;
	i = 0;

	while (fileOk) {
		stringstream ss;
		//ss<<dirname<<"/Card0230_"<<setfill('0')<<setw(4)<<i+1<<"_events.txt";
		ss << dirname << "/Card" << cardNo << "_" << setfill('0') << setw(4)
				<< i + 1 << ".evt";
		cout << "reading " << ss.str().c_str() << endl;
		fileOk = ReadFileBin(&ss);
		if (fileOk)
			cout << "		file read succesfully; total no of events:" << size()
					<< endl;
		cout << "                                       last timestamp in file "
				<< cCaenEvent::lastTimestamp << " (sec)  corrected:"
				<< cCaenEvent::lastTimestamp + cCaenEvent::correctionTime
				<< "(sec)" << endl;

		i++;
		//DoOtherMath();
		//this->Print();
	};

	//DoOtherMath();

	return 1;
}

//int cEventList::ReadFile(stringstream *ss){
//
//	char ifName[256];
//	strcpy(ifName,ss->str().c_str());
//	ifstream ifile(ifName,ios::in);
//	if(!ifile){
//		cout<<"		file "<<ifName<<" does not exists; reading finished"<<endl<<endl;;
//		return 0;
//	};
//	char blindline[256]; //the first line must be skipped: ... "Channel Time@stamp Trigger_n° Energy(0-32768)"
//   		 ifile.getline(blindline,256);
//	cCaenEvent event;
//	while(ifile>>event){
//		try{
//			data.push_back(event);
//		}
//		catch (bad_alloc&)
//		{
//		 cout<<"error alocating memory in ReadFile"<<endl;
//		 cout<<"max size of data array:  "<<data.max_size()<<endl;
//		 cout<<"capacity of data array:  "<<data.capacity()<<endl;
//		 cout<<"size of data array:  "<<data.size()<<endl;
//		 data.resize(data.max_size());
//
//		 continue;
//		};
//		if(event.isPileUp)markedPileUp++;
//	};
//	ifile.close();
//	ifile.clear();
//	cout<<"								max size of data array:  "<<data.max_size()<<endl;
//	cout<<"								capacity of data array:  "<<data.capacity()<<endl;
//
//	return 1;
//};

int cEventList::ReadFileBin(stringstream *ss) { //varianta cu citire in C, ca la razvan

	char ifName[256];
	strcpy(ifName, ss->str().c_str());

	uint8_t a[14]; // buffer used to read from TNT2 .evt files
	unsigned long long int timestamp = 0, oldtimestamp;
	unsigned int trigger = 0;
	unsigned int energy = 0;
	unsigned int channel = 0;

	FILE *fr;
	fr = fopen(ifName, "rb");
	if (!fr) {
		cout << "		file " << ifName << " does not exists; reading finished"
				<< endl << endl;
		;
		return 0;
	};

	while (14 == fread(a, 1, 14, fr)) {
		timestamp = 0;
		energy = 0;
		channel = 0;
		trigger = 0;
		for (int i = 0; i < 6; i++) {
			timestamp += a[i];
			timestamp <<= 8; // shifts to the left with 8 bits. See "Bitwise operations in C"
		}
		timestamp >>= 8;
		if (timestamp == 0)
			continue; // to remove the dummy events
		for (int i = 6; i < 10; i++) {
			trigger += a[i];
			trigger <<= 8;
		}
		trigger >>= 8;
		energy += a[10];
		energy <<= 8;
		energy += a[11];
		//if (energy < 0)
		//energy = -energy; // to compensate the negative energies
		energy = 65535 - energy; // to compensate the negative energies
		//energy=1000;
		channel = a[13];

		//printf ( "%d\t%llu\t%d\t\n", channel, timestamp, energy);  //for testing

		if (channel > 21)
			continue; //to remove events with channel ID not known
		//!todo what are channel id's >21?
		cCaenEvent event;
		event.Set(timestamp, energy, trigger, channel);
		//cout<<event;
		try {
			data.push_back(event);
		} catch (bad_alloc&) {
			cout << event.timestamp << "  " << event.energy << "   "
					<< event.detNr << "  " << event.trigId << endl;
			;
			cout << "error alocating memory" << endl;
			cout << "max size of data array:  " << data.max_size() << endl;
			cout << "capacity of data array:  " << data.capacity() << endl;
			cout << "size of data array:  " << data.size() << endl;
			data.resize(data.max_size());
			cout << event.timestamp << "  " << event.energy << "   "
					<< event.detNr << "  " << event.trigId << endl;
			;

			continue;
		};
		if (event.isPileUp)
			markedPileUp++;
		//cout<<event<<endl;

	};
	//fclose(fr);
	cout << "								max size of data array:  " << data.max_size() << endl;
	cout << "								capacity of data array:  " << data.capacity() << endl;

	return 1;
}
;

int cEventList::ReadFileBin(stringstream *ss, int detId) { //varianta cu citire in C, ca la razvan

	char ifName[256];
	strcpy(ifName, ss->str().c_str());

	uint8_t a[14]; // buffer used to read from TNT2 .evt files
	unsigned long long int timestamp = 0, oldtimestamp;
	unsigned int trigger = 0;
	unsigned int energy = 0;
	unsigned int channel = 0;

	FILE *fr;
	fr = fopen(ifName, "rb");
	if (!fr) {
		cout << "		file " << ifName << " does not exists; reading finished"
				<< endl << endl;
		;
		return 0;
	};

	while (14 == fread(a, 1, 14, fr)) {
		timestamp = 0;
		energy = 0;
		channel = 0;
		trigger = 0;
		for (int i = 0; i < 6; i++) {
			timestamp += a[i];
			timestamp <<= 8; // shifts to the left with 8 bits. See "Bitwise operations in C"
		}
		timestamp >>= 8;
		if (timestamp == 0)
			continue; // to remove the dummy events
		for (int i = 6; i < 10; i++) {
			trigger += a[i];
			trigger <<= 8;
		}
		trigger >>= 8;
		energy += a[10];
		energy <<= 8;
		energy += a[11];
		if (energy < 0)
			energy = -energy; // to compensate the negative energies
		//energy = energy+65535; // to compensate the negative energies
		energy = 1000;
		channel = a[13];

		//printf ( "%d\t%llu\t%d\t\n", channel, timestamp, energy);  //for testing

		cCaenEvent event;
		event.Set(timestamp, energy, trigger, channel);
		//cout<<event;
		try {
			if (event.detNr == detId || event.detNr == detId + 16)
				data.push_back(event);
		} catch (bad_alloc&) {
			cout << event.timestamp << "  " << event.energy << "   "
					<< event.detNr << "  " << event.trigId << endl;
			;
			cout << "error alocating memory in readFileBin" << endl;
			cout << "max size of data array:  " << data.max_size() << endl;
			cout << "capacity of data array:  " << data.capacity() << endl;
			cout << "size of data array:  " << data.size() << endl;
			data.resize(data.max_size());
			cout << event.timestamp << "  " << event.energy << "   "
					<< event.detNr << "  " << event.trigId << endl;
			;

			continue;
		};
		if (event.isPileUp
				&& (event.detNr == detId || event.detNr == detId + 16)) {
			//cout<<event<<endl;
			markedPileUp++;
		};

	};

	cout << "								max size of data array:  " << data.max_size() << endl;
	cout << "								capacity of data array:  " << data.capacity() << endl;

	return 1;
}
;

/*int cEventList::ReadFileBin(stringstream *ss){

 char ifName[256];
 strcpy(ifName,ss->str().c_str());
 ifstream ifile(ifName,ios::in|ios::binary);
 if(!ifile){
 cout<<"		file "<<ifName<<" does not exists; reading finished"<<endl<<endl;;
 return 0;
 };

 while(!ifile.eof()){
 uint8_t buffer[16];
 ifile.read (buffer, 14);

 cCaenEvent event;
 event.DecodeFromBinary(buffer);
 //cout<<event;
 try{
 data.push_back(event);
 }
 catch (bad_alloc&)
 {
 cout<<"error alocating memory"<<endl;
 cout<<"max size of data array:  "<<data.max_size()<<endl;
 cout<<"capacity of data array:  "<<data.capacity()<<endl;
 cout<<"size of data array:  "<<data.size()<<endl;
 data.resize(data.max_size());

 continue;
 };
 if(event.isPileUp)markedPileUp++;
 //delete buffer;
 };

 ifile.close();
 ifile.clear();
 cout<<"								max size of data array:  "<<data.max_size()<<endl;
 cout<<"								capacity of data array:  "<<data.capacity()<<endl;

 return 1;
 };
 */
ostream& operator<<(ostream& output, const cEventList& p) {
	return output;
}

istream& operator>>(istream& input, cEventList& p) {

	return input;
}

void cEventList::Print() {
	cout << "total number of events in list: " << name << "   " << size()
			<< endl;
	cout << "		time interval: " << data.front().timestamp << "  to "
			<< data.back().timestamp << " seconds" << endl;
	cout << "		realTime:" << realTime << " seconds" << endl;
	cout << "		lifeTime:" << lifeTime << " seconds" << endl;
	cout << "     deadTime:" << deadTime << "  seconds" << endl;
	cout << "				histo t:" << noBinsForHisto << " bins, max at " << maxTforHisto
			<< endl;

	cout << "		marked as PileUp by the acquisition: " << markedPileUp << " ("
			<< markedPileUp / (double) size() * 100 << "%)" << endl;
	cout << "		rejected because of dead Time : " << markedDeadTime << " ("
			<< markedDeadTime / (double) size() * 100 << "%)" << endl;
}
;

//int cEventList::getFromListId(cEventList* bigList,int id){//select a certain detector Nr from the full list
//
//	vector<cCaenEvent>::iterator it;
//	for( it=bigList->data.begin(); it<bigList->data.end();it++){
//		//cout<<it->detNr<<endl;
//		if(it->detNr==id) {
//			//cout<<*it<<endl;
//			try{
//			data.push_back(*it);
//			}
//			catch (bad_alloc&)
//			{
//				 cout<<"error alocating memory in getFromListId"<<endl;
//		 	cout<<"max size of data array:  "<<data.max_size()<<endl;
//		 	cout<<"capacity of data array:  "<<data.capacity()<<endl;
//		 	cout<<"size of data array:  "<<data.size()<<endl;
//		 	//data.resize(data.max_size());
//		 	//while(1){};
//			};
//			//data.push_back(*it);
//			if(it->isPileUp)markedPileUp++;
//			};
//
//	};
//
//	DoOtherMath();
//
//}

void cEventList::DoOtherMath() {

	realTime = data.back().timestamp - data.front().timestamp;
	//cout<<"back "<<data.back().timestamp<<"  front"<<data.front().timestamp<<endl;
	int exp;
	exp = pow(10, floor(log10(realTime)));
	maxTforHisto = ceil(realTime / exp) * exp;

	if (exp < 10000)
		noBinsForHisto = maxTforHisto;
	else
		noBinsForHisto = ceil(realTime / exp) * 1000;

	startTime = data.at(0).timestamp;
	deadTime = (realTime - lifeTime) / (size() - markedDeadTime);
	//cout<<endl<<realTime-lifeTime<<"  "<<size()-markedDeadTime<<"  "<<deadTime<<endl;

}

//void cEventList::BuildPileUpDistr(){
//	//TH1F *h1=new TH1F("pileupdistr_det2","pileupdistr_det2",noBinsForHisto,0,maxTforHisto);
//	//TH1F *h2=new TH1F("pileupdistr_det2_en","pileupdistr_det2_en",1024,0,8191);
//	TH2F *histET=new TH2F("pileupdistrET","time energydistribution",noBinsForHisto,0,maxTforHisto, 1024,0,8191);
//
//	vector<cCaenEvent>::iterator it;
//	for( it=data.begin(); it<data.end();it++){
//		//cout<<it->detNr<<endl;
//		if(it->isPileUp==1) {
//			//h1->Fill(it->timestamp);
//			//h2->Fill(it->energy);
//			histET->Fill(it->timestamp,it->energy);
//		};
//	};
//	//h1->Write();
//	//delete h1;
//	//h2->Write();
//	//delete h2;
//	histET->Write();
//	delete histET;
//}
//void cEventList::BuildETMatrix(){
//	TH2F *histET1=new TH2F("histET","time energydistribution",noBinsForHisto,0,maxTforHisto, 32768,0,32767);
// 	TH2F *histET2=new TH2F("histET_rejectedDT","time energydistribution",noBinsForHisto,0,maxTforHisto, 32768,0,32767);
// 	//cout<<"using 16383"<<endl;
//	vector<cCaenEvent>::iterator it;
//	for( it=data.begin(); it<data.end();it++){
//		if(it->isDead==0) histET1->Fill(it->timestamp-data.begin()->timestamp, it->energy);
//		else  histET2->Fill(it->timestamp-data.begin()->timestamp, it->energy);
//	};
//
//	histET1->Write();
//	delete histET1;
//	histET2->Write();
//	delete histET2;
//
//}
//
//void cEventList::markDeadTime(int type, int value){
//	markedDeadTime=0;
//	lifeTime=0;
//	double dead;
//	dead=value/1000000.; //sec
//	if(type==0){
//		markDeadTimeNEDT(dead);
//	}else{
//		markDeadTimeEDT(dead);
//	};
//
//
//}
//void cEventList::markDeadTimeNEDT(double dead){
//	cout<<endl<<"non extending dead time (NEDT) will be applied to list "<<name<<"  "<<dead<<" sec" <<endl;
//	double safetime;
//	safetime=0;
//	vector<cCaenEvent>::iterator it;
//	for( it=data.begin(); it<data.end();it++){
//		if(it->timestamp>safetime) {
//			it->isDead=0;
//			//cout.width(19);
//			//cout.precision(10);
//			//cout<<safetime<<" ";
//			//cout.width(29);
//			//cout.precision(10);
//			//cout.setf(ios::fixed,ios::floatfield);
//			//cout<<it->timestamp<<"  ";;
//			lifeTime=lifeTime+(it->timestamp-safetime);
//			safetime=it->timestamp+dead;
//
//			//cout.width(19);
//			//cout.precision(10);
//			//cout<<safetime<<"  ";
//
//			//cout.width(19);
//			//cout.precision(10);
//			//cout<<lifeTime<<endl;;
//
//
//		}else {
//			it->isDead=1;
//			markedDeadTime++;
//		};
//	};
//
//}
//void cEventList::markDeadTimeEDT(double dead){
//	cout<<endl<<"extending dead time (EDT) will be applied to list "<<name<<"  "<<dead<<" sec"<<endl;
//	double safetime;
//	safetime=0;
//	vector<cCaenEvent>::iterator it;
//	for( it=data.begin(); it<data.end();it++){
//		if(it->timestamp>safetime) {
//			it->isDead=0;
//			lifeTime=lifeTime+it->timestamp-safetime;
//			safetime=it->timestamp+dead;
//		}else {
//			it->isDead=1;
//			safetime=it->timestamp+dead;
//			markedDeadTime++;
//		};
//	};
//
//}
//
//void cEventList::BuildTimeIntervalDistribution(int elow, int ehigh, int scale){
//	TH1F *h2=new TH1F("TID","time interval distribution",10000,0,scale*100./1000000.);
//	//chances are that the first event in the list is not in gate; the first portion will just skip events until the first one is reached
//	int firstNotFound=1;
//	vector<cCaenEvent>::iterator it1;
//	double lastTime;
//
//	it1=data.begin();
//
//	while(firstNotFound||it1==data.end()){
//
//	 	if(it1->energy>elow&&it1->energy<ehigh&&it1->isDead==0) {
//
//			lastTime=it1->timestamp;
//			firstNotFound=0;
//		};
//		it1++;
//
//	};
//
//	vector<cCaenEvent>::iterator it;
//
//	for( it=it1; it<data.end();it++){
//		if(it->energy>elow&&it->energy<ehigh&&it->isDead==0) {
//	 		h2->Fill(it->timestamp-lastTime);
//			lastTime=it->timestamp;
//		};
//	};
//	h2->Write();
//	delete h2;
//
//}
//
//void cEventList::BuildTimeIntervalDistribution(int elow, int ehigh, int nBins, float max){
//	TH1F *h2=new TH1F("TID","time interval distribution",nBins,0,max);
//	//TH2F *h3=new TH2F("TID_En_matrix","time interval distribution energy matrix",nBins,0,max,8192,0,8191);
//	TH2F *h4=new TH2F("TID_Time_matrix","time interval distribution time matrix",nBins,0,max,noBinsForHisto,0,maxTforHisto);
//	//chances are that the first event in the list is not in gate; the first portion will just skip events until the first one is reached
//	int firstNotFound=1;
//	vector<cCaenEvent>::iterator it1;
//	double lastTime;
//
//	it1=data.begin();
//
//	while(firstNotFound||it1==data.end()){
//
//	 	if(it1->energy>elow&&it1->energy<ehigh&&it1->isDead==0) {
//
//			lastTime=it1->timestamp;
//			firstNotFound=0;
//		};
//		it1++;
//
//	};
//
//	vector<cCaenEvent>::iterator it;
//
//	for( it=it1; it<data.end();it++){
//		if(it->energy>elow&&it->energy<ehigh&&it->isDead==0) {
//	 		h2->Fill(it->timestamp-lastTime);
//			//h3->Fill(it->timestamp-lastTime,it->energy);
//			h4->Fill(it->timestamp-lastTime,it->timestamp);
//			//cout<<it->timestamp-lastTime<<"  "<<it->timestamp<<endl;
//			lastTime=it->timestamp;
//		};
//	};
//	//h2->Dump();
//	//h3->Dump();
//	//h4->Dump();
//	h2->Write();
//	//cout<<"h2 written"<<endl;
//	delete h2;
//	//cout<<"writing h3"<<endl;
//	//h3->Write();
//	//cout<<"h3 written"<<endl;
//	//delete h3;
//	h4->Write();
//	//cout<<"h4 written"<<endl;
//	delete h4;
//
//}
//
//
//
//void cEventList::BuildTimeAnalysisMatrixSimple(int e1low, int e1high,int e2low, int e2high, double deltaT){
//	TH2F *histET2=new TH2F("histET_TIA","time_energy distribution",10000,0,deltaT/1000000., 1024,0,8191);
//  	TH2F *histET3=new TH2F("histTT_TIA","time_time distribution",10000,0,deltaT/1000000., noBinsForHisto,0,maxTforHisto);
//
//	int firstNotFound=1;
//	vector<cCaenEvent>::iterator it1;
//	double lastTime;
//
//	it1=data.begin();
//
//	while(firstNotFound||it1==data.end()){
//
//	 	if(it1->energy>e1low&&it1->energy<e1high&&it1->isDead==0) {
//
//			lastTime=it1->timestamp;
//			firstNotFound=0;
//		};
//		it1++;
//	};
//
//	vector<cCaenEvent>::iterator it;
//	for( it=it1; it<data.end();it++){
//		if(it->energy>e2low&&it->energy<e2high&&it->isDead==0) {
//	 		histET2->Fill(it->timestamp-lastTime, it->energy);
//			histET3->Fill(it->timestamp-lastTime, it->timestamp);
//		};
//		if(it->energy>e1low&&it->energy<e1high&&it->isDead==0) {
//	 		lastTime=it->timestamp; //reset the timer if an event in the first gate is found
//		};
//	};
//	histET2->Write();
//	delete histET2;
//	histET3->Write();
//	delete histET3;
//
//};
//
//void cEventList::BuildTimeAnalysisMatrixSimple2(int e1low, int e1high,int e2low, int e2high, double deltaT){
//	TH2F *histET2=new TH2F("histET_TIA2","time_energy distribution no reset",10000,0,deltaT/1000000., 1024,0,8191);
//  	TH2F *histET3=new TH2F("histTT_TIA2","time_time distribution no reset",10000,0,deltaT/1000000., noBinsForHisto,0,maxTforHisto);
//
//	int firstNotFound=1;
//	vector<cCaenEvent>::iterator it1;
//	double lastTime;
//
//	it1=data.begin();
//
//	while(firstNotFound||it1==data.end()){
//
//	 	if(it1->energy>e1low&&it1->energy<e1high&&it1->isDead==0) {
//
//			lastTime=it1->timestamp;
//			firstNotFound=0;
//		};
//		it1++;
//	};
//
//	vector<cCaenEvent>::iterator it;
//	int daughterDetected=0;
//	for( it=it1; it<data.end();it++){
//		if(it->energy>e2low&&it->energy<e2high&&it->isDead==0) {
//	 		histET2->Fill(it->timestamp-lastTime, it->energy);
//			histET3->Fill(it->timestamp-lastTime, it->timestamp);
//			daughterDetected=1;
//		};
//		if(it->energy>e1low&&it->energy<e1high&&it->isDead==0) {
//			if(daughterDetected||it->timestamp-lastTime>deltaT/1000000.){
//				lastTime=it->timestamp; 					//if another mother is detected  reset the timer if: the daughter of the previous mother was detected
//				daughterDetected=0;																				// OR enough time has passed from the previous mother
//			};
//		};
//	};
//	histET2->Write();
//	delete histET2;
//	histET3->Write();
//	delete histET3;
//
//};
//
//void cEventList::BuildTimeAnalysisMatrixSimple3(int e1low, int e1high,int e2low, int e2high, double deltaT){
//	TH2F *histET2=new TH2F("histET_TIA3","time_energy distribution tove",10000,0,deltaT/1000000., 1024,0,8191);
//  	TH2F *histET3=new TH2F("histTT_TIA3","time_time distribution tove",10000,0,deltaT/1000000., noBinsForHisto,0,maxTforHisto);
//
//	int firstNotFound=1;
//	vector<cCaenEvent>::iterator it1;
//	double lastTime;
//	double firstTime;  // if the run is split, the start time needs to be set to 0 (the first time in the list is used as a time reference)
//
//	it1=data.begin();
//	firstTime=it1->timestamp;
//
//	while(firstNotFound||it1==data.end()){
//
//	 	if(it1->energy>e1low&&it1->energy<e1high&&it1->isDead==0) {
//
//			lastTime=it1->timestamp;
//			firstNotFound=0;
//		};
//		it1++;
//	};
//
//	vector<cCaenEvent>::iterator it;
//	for( it=it1; it<data.end();it++){
//		if(it->energy>e2low&&it->energy<e2high&&it->isDead==0&&it->timestamp-lastTime<deltaT/1000000.) {
//	 		histET2->Fill(it->timestamp-lastTime, it->energy);
//			histET3->Fill(it->timestamp-lastTime, it->timestamp-firstTime);
//		};
//		if(it->energy>e1low&&it->energy<e1high&&it->isDead==0) {
//			if(it->timestamp-lastTime>deltaT/1000000.){
//				lastTime=it->timestamp; 					//if the time has elapsed, reset the timer with a gamma1 event
//			};
//		};
//	};
//	histET2->Write();
//	delete histET2;
//	histET3->Write();
//	delete histET3;
//
//};
//
//
//void  cEventList::WriteFileData(TFile *f, cInputInfo *info){
//	f->cd();
//	f->cd(info->ssdir.str().c_str());
//	TH1F *t1=new TH1F("fileStats","file stats",10,1,11);
//	t1->SetBinContent(1,realTime);
//	t1->SetBinContent(2,size());
//	t1->SetBinContent(3,noBinsForHisto);
//	t1->SetBinContent(4,maxTforHisto);
//	t1->SetBinContent(5,markedPileUp);
//	t1->SetBinContent(6,markedPileUp/(double)size()*100);
//
//	t1->Write();
//	gDirectory->cd(info->ssDT.str().c_str());
//
//	t1->SetTitle("DT stats");
//	t1->SetName("DTstats");
//	t1->SetBinContent(7,markedDeadTime);
//	t1->SetBinContent(8,markedDeadTime/(double)size()*100);
//	t1->Write();
//	delete t1;
//};

void cEventList::MakeDetectorList() {

	cout << "events in list:" << data.size() << endl;
	//detIds.resize(data.size());
	set<int> s;

	for (int i = 0; i < data.size(); i++) {
		s.insert(data.at(i).detNr);
		//if(data.at(i).detNr>20)cout<<data.at(i)<<endl;
		//detIds.push_back(data.at(i).detNr);
	};
	detIds.assign(s.begin(), s.end());

	cout << "detectors in list: " << detIds.size() << endl;
	;
	for (int i = 0; i < detIds.size(); i++) {
		cout << detIds[i] << "  ";
	};
	cout << endl;
	//sort(detIds.begin(), detIds.end());
}
;

void cEventList::CalibrateEnergy() {

	for (int i = 0; i < data.size(); i++) {
		//cout << "adding det no: " << data.at(i).detNr << endl;
		std::vector<int>::iterator it;
		it = find(detIds.begin(), detIds.end(), data.at(i).detNr);
		int position;
		position = it - detIds.begin();
		//cout<<"is at position "<<position<<endl;
		//cout<<"incrementing spectra "<<detSpectra.at(position)->GetName()<<endl<<endl;
		data.at(i).realEnergy = enCal.at(position).ComputeEnergy(
				data.at(i).energy);
		if (enCal.at(position).detId != detIds.at(position)) {
			cout << "energy calibration crossing " << enCal.at(position).detId
					<< "  " << detIds.at(position) << "  " << position << endl;

		};;
	};
}
;

void cEventList::MakeSpectraSingle() {

	for (int i = 0; i < data.size() - eventsStored; i++) {
		//cout << "adding det no: " << data.at(i).detNr << endl;
		std::vector<int>::iterator it;
		it = find(detIds.begin(), detIds.end(), data.at(i).detNr);
		int position;
		position = it - detIds.begin();
		//cout<<"is at position "<<position<<endl;
		//cout<<"incrementing spectra "<<detSpectra.at(position)->GetName()<<endl<<endl;
		detSpectra.at(position)->Fill(data.at(i).realEnergy);
		;
	};

}
;

void cEventList::MakeEmptySpectras() {

	cout << "making spectra for " << detIds.size() << " detectors" << endl;

	for (int i = 0; i < detIds.size(); i++) {
		stringstream ss;
		ss << "spec_" << detIds.at(i);
		TH1F *spec = new TH1F(ss.str().c_str(), ss.str().c_str(), 16384, 0,
				65535);
		detSpectra.push_back(spec);

		stringstream ss2;
		ss2 << "ETmat_" << detIds.at(i);
		TH2F *mat = new TH2F(ss2.str().c_str(), ss2.str().c_str(), 16384, 0,
				65535, 2000, -4E-6, 50E-6);
		matrices.push_back(mat);
		addBackMat = new TH2F("addBackMat", "addBackMat", 16384, 0, 65535, 2000,
				-4E-6, 50E-6);
	};
	for (int i = 0; i < detSpectra.size(); i++) {
		cout << detSpectra.at(i)->GetName() << endl;
	};

	//TID

	double maxtime = 0.010; //seconds
	cout << "making TID for " << detIds.size() << " detectors" << endl;

	for (int i = 0; i < detIds.size(); i++) {
		stringstream ss;
		ss << "TID_" << detIds.at(i);
		TH1F *spec = new TH1F(ss.str().c_str(), ss.str().c_str(), 10000, 0,
				maxtime);
		detTID.push_back(spec);
		lastTimeStamp.push_back(0);

	};
	for (int i = 0; i < detTID.size(); i++) {
		cout << detTID.at(i)->GetName() << endl;
	};
	globalTID = new TH1F("global_TID", "global_TID", 1000, 0, 1E-6);
	globalTID2 = new TH1F("global_TID2", "global_TID2", 1000, 0, 1E-6);
	globalTID3 = new TH1F("global_TID3", "global_TID3", 1000, 0, 1E-6);
	globalTID4 = new TH1F("global_TID4", "global_TID4", 1000, 0, 1E-6);
	currentTimeStamp = 0;
	addBackSpec = new TH1F("addBack", "addBack", 16384, 0, 65535);

}
;
void cEventList::WriteSpectraSingle(char dirName[256], int cardNo) {
	cout << "writing spectra single" << endl;
	for (int i = 0; i < detSpectra.size(); i++) {
		stringstream ss;
		ss << dirName << "_" << cardNo << "_spectra" << i << ".out";
		ofstream ofile(ss.str().c_str());

		for (int j = 0; j < 16384; j++) {
			ofile << detSpectra.at(i)->GetBinContent(j) << endl;
		};

	};

	stringstream ss2;
	ss2 << dirName << "_" << cardNo << "_addBack.out";
	ofstream ofile(ss2.str().c_str());

	for (int j = 0; j < 16384; j++) {
		ofile << addBackSpec->GetBinContent(j) << endl;
	};

}
;

void cEventList::WriteResults(char dirName[256], int cardNo) {
	cout << "writing spectra single" << endl;
	stringstream ss;
	ss << dirName << "_" << cardNo << "_results.root";
	TFile *f = new TFile(ss.str().c_str(), "RECREATE");
	f->cd();
	for (int i = 0; i < detSpectra.size(); i++) {
		detSpectra.at(i)->Write();
		matrices.at(i)->Write();
	};
	addBackSpec->Write();
	addBackMat->Write();

	f->Close();
	delete f;

}
;
void cEventList::ReadCalibration(char dirname[256], int cardNo) {

	stringstream ss;
	ss << dirname << "/" << cardNo << "enCal.dat";
	ifstream calFile(ss.str().c_str());
	if (!calFile) {
		cout << "calibration file " << ss.str().c_str() << " not found..."
				<< endl;
		exit(1);
	};
	EnergyCalibration cal;
	while (calFile >> cal) {
		enCal.push_back(cal);
	};
	//cout<<" Calibrations read: "<<enCal.size()<<endl;
	//for(int i=0;i<enCal.size();i++)cout<<enCal.at(i)<<endl;
	for (int i = 0; i < enCal.size(); i++) {
		if (enCal.at(i).detId != detIds.at(i)) {
			cout
					<< "the order of detectors is not the order of detectors in the calibration"
					<< endl;
			cout << enCal.at(i).detId << "  " << detIds[i] << endl;
		};
	};
	for (int i = enCal.size(); i < detIds.size(); i++) {
		EnergyCalibration cal2;
		cal2.detId = detIds.at(i);
		enCal.push_back(cal2);
	};

	for (int i = 0; i < enCal.size(); i++) {
		cout << enCal[i] << endl;
	};

}
;

void cEventList::MakeTIDSingle() {

	for (int i = 0; i < data.size() - eventsStored; i++) {
		//for (int i = 0; i < 100; i++) {
		//cout << "adding det no: " << data.at(i).detNr << endl;
		std::vector<int>::iterator it;
		it = find(detIds.begin(), detIds.end(), data.at(i).detNr);
		int position;
		position = it - detIds.begin();
		//cout<<"is at position "<<position<<endl;
		//cout<<data.at(i)<<endl;
		//cout<<"incrementing spectra "<<detTID.at(position)->GetName()<<" with value:" <<data.at(i).timestamp-lastTimeStamp.at(position) <<endl<<endl;
		detTID.at(position)->Fill(
				data.at(i).timestamp - lastTimeStamp.at(position));
		//cout<<lastTimeStamp.at(position)<<endl;
		lastTimeStamp.at(position) = data.at(i).timestamp;

		globalTID->Fill(data.at(i).timestamp - currentTimeStamp);
		globalTID2->Fill(data.at(i + 1).timestamp - currentTimeStamp);
		globalTID3->Fill(data.at(i + 2).timestamp - currentTimeStamp);
		globalTID4->Fill(data.at(i + 3).timestamp - currentTimeStamp);

		currentTimeStamp = data.at(i).timestamp;
		;
	};
//		for (int i = 0; i < detTID.size(); i++) {
//					cout << detTID.at(i)->GetName() << endl;
//					TCanvas *c2 =new TCanvas();
//					detTID.at(i)->Draw();
//					c2->WaitPrimitive();
//					delete c2;
//				};
//		TCanvas *c2 =new TCanvas();
//		c2->Divide(1,4);
//		c2->cd(1);
//		globalTID->Draw();
//	c2->cd(2);
//	globalTID2->Draw();
//	c2->cd(3);
//		globalTID3->Draw();
//		c2->cd(4);
//			globalTID4->Draw();
//			c2->WaitPrimitive();
//	delete c2;

}
;
void cEventList::MakeTIDAll() {

}
;

void cEventList::MakeMatrices() {

	double eventTimeStamp;
	eventTimeStamp = 0;
	int eventMultiplicity;
	eventMultiplicity = 0;
	double addBackEnergy;
	double addBackTimeStamp;
	addBackEnergy = 0;
	addBackTimeStamp = 0;
	double pulserTimeStamp;
	pulserTimeStamp = 0;
	//for (int i = 0; i < 100; i++) {
	//find a pulser(RF) event in the list
	int k = 0;
	while (pulserTimeStamp < 0) {
		if (data.at(k).detNr == 5)
			pulserTimeStamp = data.at(k).timestamp;
		k = k + 1;
	};

	for (int i = k; i < data.size() - eventsStored; i++) {
		std::vector<int>::iterator it;
				it = find(detIds.begin(), detIds.end(), data.at(i).detNr);
				int position;
				position = it - detIds.begin();
		if (data.at(i).detNr < 5) {
			matrices.at(position)->Fill(data.at(i).realEnergy,
					data.at(i).timestamp - pulserTimeStamp);
			//cout << data.at(i).detNr<<"  "<<(data.at(i).timestamp - pulserTimeStamp)/1E-6 << endl;
			if (data.at(i).timestamp - eventTimeStamp < 1E-6) {
				eventMultiplicity++;
				addBackEnergy = addBackEnergy + data.at(i).realEnergy;
				addBackTimeStamp = data.at(i).timestamp;
				//cout<<data.at(i).detNr<<"  ";
			} else {
				//cout<<data.at(i).timestamp<<"  "<<eventTimeStamp<<"  "<<data.at(i).timestamp-eventTimeStamp<<endl;
				eventTimeStamp = data.at(i).timestamp;
				eventMultiplicity = 1;
				addBackSpec->Fill(addBackEnergy);
				addBackMat->Fill(addBackEnergy,
						eventTimeStamp - pulserTimeStamp);

				addBackEnergy = data.at(i).realEnergy;

			};
		} else {
			//cout << data.at(i).detNr << endl;
			if (data.at(i).detNr == 6)
				//cout << "event ended; \n mult=" << eventMultiplicity << "  "<<addBackEnergy<<"  "<<pulserTimeStamp<<endl;
				pulserTimeStamp = data.at(i).timestamp;
		};
	};
//	TCanvas *c3= new TCanvas();
//	spec->Draw();
//	c3->WaitPrimitive();
//	delete c3;

}
;

void cEventList::CleanData() {
	data.erase(data.begin(), data.end() - eventsStored);

}
;
